import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:xws/helpers/safe_value_notifier.dart';
import 'package:xws/res/icons.dart';
import 'package:xws/res/images.dart';
import 'package:xws/res/urls.dart';
import 'package:xws/ui/root/app_root.dart';
import 'package:xws/utils/app_util.dart';
import 'package:xws/utils/data_util.dart';
import 'package:xws/utils/dio_utils/request/user_req.dart';
import 'package:xws/utils/storage_util.dart';
import 'package:xws/utils/theme_util.dart';
import 'package:xws/utils/tools_util.dart';
import 'package:xws/widgets/app_btn.dart';
import 'package:xws/widgets/app_img.dart';
import 'package:xws/widgets/app_text_field.dart';
import 'package:xws/widgets/back_icon.dart';
import 'package:xws/widgets/ex_value_builder.dart';
import 'package:xws/widgets/safe_scaffold.dart';
import 'package:xws/widgets/shake_widget.dart';

import 'count_down.dart';

class _Agree {
  _Agree({this.select, this.shake});

  _Agree.init() {
    select = false;
    shake = false;
  }

  _Agree doShake() {
    return _Agree(
      select: select,
      shake: !(shake ?? true),
    );
  }

  _Agree doSelect() {
    return _Agree(
      select: !(select ?? false),
      shake: shake,
    );
  }

  bool? select;
  bool? shake;
}

/// 登录界面
class LoginPage extends StatefulWidget {
  const LoginPage({Key? key, this.withBack = false}) : super(key: key);

  @override
  _LoginPageState createState() => _LoginPageState();

  final bool withBack;
}

class _LoginPageState extends State<LoginPage> {
  late SafeValueNotifier<_Agree> _agree;

  late String _tel = getV<String>('phone') ?? '';
  String _code = '';

  @override
  void initState() {
    super.initState();
    _agree = SafeValueNotifier<_Agree>(_Agree.init());
  }

  @override
  void dispose() {
    _agree.dispose();
    super.dispose();
  }

  /// 获取验证码
  Future<bool> _getCode() async {
    final bool r = await _checkTel();
    if (!r) return false;

    loading(context);
    final bool s = await getSmsCode(_tel);
    close(context);

    return s;
  }

  /// 登录
  Future<void> _login() async {
    if (!(_agree.value.select ?? false)) {
      _agree.value = _agree.value.doShake();
      return;
    }

    final bool r = await _checkTel() && _checkCode();
    if (!r) return;

    loading(context);
    final String? token = await userLogin(_tel, _code);
    close(context);

    if (token == null) return;

    setV('token', token);
    setV('phone', _tel);

    push(context, const AppRoot(), remove: true);
  }

  /// 检查号码
  Future<bool> _checkTel() async {
    if (_tel.trim().isEmpty) {
      ct('请输入手机号');
      return false;
    }

    final bool r = await isPhone(_tel);
    if (!r) {
      ct('号码有误');
      return false;
    }

    return true;
  }

  /// 检查Code
  bool _checkCode() {
    if (_code.trim().isEmpty) {
      ct('请输入验证码');
      return false;
    }

    return true;
  }

  @override
  Widget build(BuildContext context) {
    initToast(context);

    return SafeScaffold(
      autoAppBar: false,
      tapToCloseKeyboard: true,
      systemNavigationBarColor: themeColor,
      systemNavigationBarBrightness: Brightness.light,
      backgroundColor: white(context),
      body: Stack(
        fit: StackFit.expand,
        alignment: Alignment.center,
        children: <Widget>[
          ClipPath(
            clipper: const _BgClipper(),
            child: ColoredBox(color: theme(context)),
          ),
          Column(
            children: <Widget>[
              _logo,
              Container(
                width: 340,
                child: _info,
                padding: const EdgeInsets.all(20),
                decoration: BoxDecoration(
                  color: white(context),
                  borderRadius: BorderRadius.circular(20),
                  boxShadow: <BoxShadow>[
                    BoxShadow(
                      color: Colors.black.withOpacity(0.05),
                      blurRadius: 20,
                    ),
                  ],
                ),
              ),
              _agreement,
            ],
          ),
          if (widget.withBack)
            Align(
              alignment: Alignment.topLeft,
              child: Padding(
                padding: const EdgeInsets.all(10.0).copyWith(top: 4 + statusBarHeight),
                child: const BackIcon(),
              ),
            ),
        ],
      ),
    );
  }

  /// logo
  Widget get _logo {
    return Expanded(
      child: Container(
        alignment: Alignment.center,
        padding: EdgeInsets.only(top: statusBarHeight),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const AppImg(url: R.logo, width: 64),
            const SizedBox(width: 90),
            Icon(
              IR.logo_text,
              size: 48,
              color: theme(context),
              textDirection: TextDirection.rtl,
            ),
          ],
        ),
      ),
    );
  }

  /// 信息输入块
  Widget get _info {
    const double fieldHeight = 60;

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      mainAxisSize: MainAxisSize.min,
      children: <Widget>[
        Center(
          child: Text(
            '登录',
            style: TextStyle(
              fontSize: 20,
              fontWeight: FontWeight.bold,
              color: black(context).withOpacity(0.7),
            ),
          ),
        ),
        const SizedBox(height: 10),
        const Text(
          '手机号:',
          style: TextStyle(fontSize: 13, fontWeight: FontWeight.bold),
        ),
        const SizedBox(height: 6),
        AppTextField(
          initialValue: _tel,
          height: fieldHeight,
          hintText: '输入手机号',
          maxLength: 20,
          fillColor: canvas(context),
          onChanged: (String v) => _tel = v,
          keyboardType: TextInputType.number,
          inputFormatters: onlyNum,
          border: OutlineInputBorder(
            borderSide: BorderSide.none,
            borderRadius: BorderRadius.circular(10),
          ),
        ),
        const SizedBox(height: 10),
        const Text(
          '验证码:',
          style: TextStyle(fontSize: 13, fontWeight: FontWeight.bold),
        ),
        const SizedBox(height: 6),
        AppTextField(
          maxLength: 10,
          height: fieldHeight,
          hintText: '输入验证码',
          fillColor: canvas(context),
          suffixIcon: CountDown(onTap: _getCode),
          onChanged: (String v) => _code = v,
          keyboardType: TextInputType.number,
          inputFormatters: onlyNum,
          border: OutlineInputBorder(
            borderSide: BorderSide.none,
            borderRadius: BorderRadius.circular(10),
          ),
        ),
        const SizedBox(height: 30),
        AppBtn.center(
          onTap: _login,
          text: '登录',
          textStyle: TextStyle(
            color: white(context),
            fontSize: 16,
            fontWeight: FontWeight.bold,
          ),
          padding: EdgeInsets.zero,
          height: 50,
          radius: 10,
        ),
      ],
    );
  }

  /// 协议勾选
  Widget get _agreement {
    return Expanded(
      child: Center(
        child: GestureDetector(
          onTap: () => _agree.value = _agree.value.doSelect(),
          child: Container(
            height: 30,
            alignment: Alignment.center,
            color: Colors.transparent,
            child: ExValueBuilder<_Agree>(
              valueListenable: _agree,
              builder: (_, _Agree agr, Widget? child) {
                return ShakeWidget(
                  key: Key(agr.shake.toString()),
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[
                      Container(
                        width: 15,
                        height: 15,
                        child: Transform.scale(
                          scale: agr.select == true ? 1 : 0,
                          child: Container(
                            alignment: Alignment.center,
                            child: Icon(
                              Icons.check_rounded,
                              size: 10,
                              color: theme(context),
                            ),
                            decoration: BoxDecoration(
                              shape: BoxShape.circle,
                              color: white(context),
                            ),
                          ),
                        ),
                        decoration: BoxDecoration(
                          shape: BoxShape.circle,
                          border: Border.all(
                            color: white(context),
                          ),
                        ),
                      ),
                      const SizedBox(width: 4),
                      RichText(
                        text: TextSpan(
                          style: TextStyle(
                            color: white(context),
                            fontSize: 13,
                            height: 1.25,
                          ),
                          text: '勾选同意',
                          children: <TextSpan>[
                            TextSpan(
                              text: '隐私政策',
                              recognizer: TapGestureRecognizer()..onTap = () => openH5(Urls.privacy),
                              style: const TextStyle(
                                decoration: TextDecoration.underline,
                                fontWeight: FontWeight.bold,
                              ),
                            ),
                            const TextSpan(text: '与'),
                            TextSpan(
                              text: '用户注册协议',
                              recognizer: TapGestureRecognizer()..onTap = () => openH5(Urls.agreemet),
                              style: const TextStyle(
                                decoration: TextDecoration.underline,
                                fontWeight: FontWeight.bold,
                              ),
                            ),
                          ],
                        ),
                      ),
                    ],
                  ),
                );
              },
            ),
          ),
        ),
      ),
    );
  }
}

/// 背景裁剪
class _BgClipper extends CustomClipper<Path> {
  const _BgClipper();

  @override
  Path getClip(Size size) {
    final double w = size.width;
    final double h = size.height;

    return Path()
      ..moveTo(0, h * 0.3)
      ..quadraticBezierTo(w * 0.7, h * 0.4, w, h * 0.7)
      ..lineTo(w, h)
      ..lineTo(0, h)
      ..close();
  }

  @override
  bool shouldReclip(covariant CustomClipper<Path> oldClipper) => true;
}
